package com.snapan.service.impl;

import com.snapan.common.PageResult;
import com.snapan.dao.FileBaseDao;
import com.snapan.dao.UserFileDao;
import com.snapan.entity.FileBase;
import com.snapan.entity.UserFile;
import com.snapan.es.entity.UserFileDocument;
import com.snapan.es.repository.UserFileDocumentRepository;
import com.snapan.service.UserFileService;
import com.snapan.util.FileContentExtractor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 用户文件关联表服务实现类
 */
@Service
@Transactional
public class UserFileServiceImpl implements UserFileService {

    @Autowired
    private UserFileDao userFileDao;
    @Autowired
    private FileBaseDao fileBaseDao;
    @Autowired
    private UserFileDocumentRepository esRepository;

    @Override
    public UserFile getById(Long id) {
        return userFileDao.selectById(id);
    }

    @Override
    public List<UserFile> getAll() {
        return userFileDao.selectAll();
    }

    @Override
    public boolean add(UserFile userFile) {
        return userFileDao.insert(userFile) > 0;
    }

    @Override
    public boolean update(UserFile userFile) {
        return userFileDao.update(userFile) > 0;
    }

    @Override
    public boolean delete(Long id) {
        return userFileDao.deleteById(id) > 0;
    }

    @Override
    public boolean softDelete(Long id) {
        boolean ok = userFileDao.softDeleteById(id) > 0;
//        if (ok) {
//            // 同步删除 ES 索引
//            deleteUserFileFromEs(id);
//        }
        return ok;
    }

    @Override
    public PageResult<UserFile> selectByPage(int pageSize, int pageNo, int userId, int parentId, String fileType) {
        // 1. 计算偏移量（分页查询的起始位置）
        int offset = (pageNo - 1) * pageSize;

        // 2. 查询核心数据：当前页列表 + 总记录数
        List<UserFile> fileList = userFileDao.selectByPage(offset, pageSize, userId, parentId, fileType); // 当前页数据
        long total = userFileDao.countByCondition(userId, parentId, fileType); // 符合条件的总记录数

        // 3. 用静态工厂方法快速创建分页结果（自动计算总页数、上下页等信息）
        return PageResult.of(pageNo, pageSize, total, fileList);
    }

    @Override
    public List<UserFile> selectByUserAndParent(Long userId, Long parentId) {
        return userFileDao.selectByUserAndParent(userId, parentId);
    }

    @Override
    public List<UserFile> selectByFileBaseId(Long fileBaseId) {
        return userFileDao.selectByFileBaseId(fileBaseId);
    }

    @Override
    public void syncAllValidUserFileToEs() {
        // 1. 查询所有有效用户文件,没被彻底删除的文件，在回收站里的不算
        List<UserFile> userFileList = userFileDao.selectAllValid();
        for (UserFile userFile : userFileList) {
            // 2. 关联查询 file_base 信息
            FileBase fileBase = fileBaseDao.selectById(userFile.getFileBaseId());
            if (fileBase == null ) { // 过滤已删除的文件基础信息
                continue;
            }
            // 3. 构建 ES 实体并同步
            UserFileDocument esDoc = buildEsDocument(userFile, fileBase);
            esRepository.save(esDoc);
            System.out.println("同步 ES 完成：userFileId=" + userFile.getId() + "，fileName=" + userFile.getFileName());
        }
        System.out.println("所有有效用户文件同步 ES 结束，共 " + userFileList.size() + " 条");
    }

    @Override
    public void syncUserFileToEs(Long userFileId) {
        // 1. 查询用户文件
        UserFile userFile = userFileDao.selectById(userFileId);
        System.out.println(userFile);
        if (userFile == null  ) {
            throw new RuntimeException("用户文件不存在或已失效");
        }
        
        // 2. 如果是文件夹（file_base_id为空），直接同步文件夹信息
        if (userFile.getFileBaseId() == null && userFile.getIsDirectory() == 1) {
            UserFileDocument esDoc = buildFolderEsDocument(userFile);
            esRepository.save(esDoc);
            return;
        }
        
        // 3. 关联查询 file_base 信息（仅对文件）
        FileBase fileBase = fileBaseDao.selectById(userFile.getFileBaseId());
        if (fileBase == null ) {
            throw new RuntimeException("文件基础信息不存在或未完成上传");
        }
        
        // 4. 同步到 ES
        UserFileDocument esDoc = buildEsDocument(userFile, fileBase);
        esRepository.save(esDoc);
    }

    @Override
    public void deleteUserFileFromEs(Long userFileId) {
        if (esRepository.existsById(userFileId)) {
            esRepository.deleteById(userFileId);
        }
    }

    /**
     * 工具方法：构建 ES 实体（关联 user_file 与 file_base）
     */
    private UserFileDocument buildEsDocument(UserFile userFile, FileBase fileBase) {
        UserFileDocument esDoc = new UserFileDocument();
        // 赋值 user_file 字段
        esDoc.setId(userFile.getId());
        esDoc.setUserId(userFile.getUserId());
        esDoc.setFileBaseId(userFile.getFileBaseId());
        esDoc.setFileName(userFile.getFileName());
        esDoc.setParentId(userFile.getParentId());
        esDoc.setDirectory(userFile.getIsDirectory() == 1);
        esDoc.setUserFileUpdateTime(userFile.getUpdateTime());
        esDoc.setUserFileDeleteTime(userFile.getDeleteTime());
        esDoc.setUserFileExpireTime(userFile.getExpireTime());
        esDoc.setRecycled(userFile.getIsRecycled()== 1);
        // 赋值 file_base 字段
        esDoc.setRealName(fileBase.getRealName());
        esDoc.setFileSize(fileBase.getFileSize());
        esDoc.setFileSuffix(fileBase.getSuffix());
        esDoc.setFilePath(fileBase.getFilePath());
        esDoc.setFileBaseUpdateTime(fileBase.getUpdateTime());
        // 提取文件内容
        esDoc.setFileContent(FileContentExtractor.extractContent(
                fileBase.getFilePath(),
                Integer.valueOf(userFile.getIsDirectory())
        ));
        return esDoc;
    }

    /**
     * 工具方法：构建文件夹的 ES 实体
     */
    private UserFileDocument buildFolderEsDocument(UserFile userFile) {
        UserFileDocument esDoc = new UserFileDocument();
        // 赋值 user_file 字段
        esDoc.setId(userFile.getId());
        esDoc.setUserId(userFile.getUserId());
        esDoc.setFileBaseId(userFile.getFileBaseId());
        esDoc.setFileName(userFile.getFileName());
        esDoc.setParentId(userFile.getParentId());
        esDoc.setDirectory(userFile.getIsDirectory() == 1);
        esDoc.setUserFileUpdateTime(userFile.getUpdateTime());
        // 文件夹没有文件基础信息，设置默认值
        esDoc.setRealName(userFile.getFileName());
        esDoc.setFileSize(0L);
        esDoc.setFileSuffix("");
        esDoc.setFilePath("");
        esDoc.setFileBaseUpdateTime(userFile.getUpdateTime());
        esDoc.setFileContent(""); // 文件夹没有内容
        return esDoc;
    }

    @Override
    public boolean checkFolderExists(Long userId, Long parentId, String folderName) {
        return userFileDao.checkFolderExists(userId, parentId, folderName);
    }

    @Override
    public UserFile createFolder(String folderName, Long userId, Long parentId) {
        // 创建文件夹记录
        UserFile folder = new UserFile();
        folder.setUserId(userId);
        folder.setFileBaseId(null); // 文件夹设置file_base_id为NULL，避免外键约束
        folder.setFileName(folderName);
        folder.setParentId(parentId);
        folder.setIsDirectory((byte) 1); // 1表示目录
        folder.setStatus((byte) 1); // 1表示正常状态
        java.util.Date now = new java.util.Date();
        folder.setCreateTime(now); // 设置创建时间
        folder.setUpdateTime(now); // 设置更新时间
        folder.setIsRecycled((byte) 0); // 0表示不在回收站
        
        // 插入数据库
        boolean success = userFileDao.insert(folder) > 0;
        if (success) {
            try {
                // 同步到ES
                syncUserFileToEs(folder.getId());
            } catch (Exception e) {
                // ES同步失败不影响文件夹创建操作的成功
            }
            return folder;
        }
        return null;
    }

    @Override
    public boolean checkNameExists(Long userId, Long parentId, String name, Long excludeId) {
        return userFileDao.checkNameExists(userId, parentId, name, excludeId);
    }

    @Override
    public boolean renameFile(Long fileId, String newName) {
        try {
            // 获取文件信息
            UserFile userFile = userFileDao.selectById(fileId);
            if (userFile == null) {
                return false;
            }
            
            // 更新文件名
            userFile.setFileName(newName);
            userFile.setUpdateTime(new java.util.Date());
            // 确保isRecycled字段不为null
            if (userFile.getIsRecycled() == null) {
                userFile.setIsRecycled((byte) 0);
            }
            
            // 更新数据库
            int updateResult = userFileDao.update(userFile);
            boolean success = updateResult > 0;
            
            if (success) {
                try {
                    // 同步到ES
                    syncUserFileToEs(fileId);
                } catch (Exception e) {
                    // ES同步失败不影响重命名操作的成功
                }
            }
            return success;
        } catch (Exception e) {
            return false;
        }
    }
}
